<!DOCTYPE html><html><style> 
html {overflow:hidden}
body {position: absolute; margin:0; padding:0;width:100%; height:100%}
canvas {display:block;border:2px solid #ccc; margin:10px auto;}
p {text-align: center; font-size:12px;color:#454545;}
</style><script src="JCanvas.js" ></script> 
<canvas id="canvas" width="600" height="400"></canvas><p></p><script > 
	var canvas = document.getElementById('canvas');
	var stage = new Stage(canvas);
	var createBall = function (radius) {
		radius = (radius === undefined) ? 20 : radius;
		return new Sprite(stage.ctx, {
			x: 0,
			y: 0,
			width: radius*2,
			draw: function () { 
				this.ctx.beginPath();
				this.ctx.arc(0, 0, this.width/2, 0, Math.PI*2, true);
				this.ctx.closePath();
				this.ctx.fillStyle = 'rgba(0,0,0,'+ Math.min(1, this.width/(2*radius)) +')';
				this.ctx.fill();
			}
		});
	};
 
	var initialize = function () {
		var focalLength = 250,
			ballR = 20,
			ballN = 20,
			balls = [],
			vpx = 0,
			vpy = 0,
			angleY = 0;
 
		for (var i=0; i<ballN; i++) {
			var ball = createBall(ballR);
			stage.addChild(ball);
			ball.xpos = Math.random() * 200 - 100;
			ball.ypos = Math.random() * 200 - 100;
			ball.zpos = Math.random() * 200 - 100;
			balls.push(ball);
		}
		vpx = canvas.width/2;
		vpy = canvas.height/2;
 
		stage.addEventListener('mousemove', function (x, y) {
			angleY = (x - vpx) * .001;
		});
		
		function rotateY(ball, angleY) {
			var cosy = Math.cos(angleY),
				siny = Math.sin(angleY),
				x1 = ball.xpos * cosy - ball.zpos * siny,
				z1 = ball.zpos * cosy + ball.xpos * siny;
			ball.xpos = x1;
			ball.zpos = z1;
 
			var scale = focalLength / (focalLength + ball.zpos);
			ball.x = vpx + ball.xpos * scale;
			ball.y = vpy + ball.ypos * scale;
			ball.width = ballR*2*scale;
		}
 
		stage.onRefresh = function () { 
			for (var i=0,ball; ball=balls[i]; i++) { rotateY(ball, angleY) }
		}
 
		stage.start();
	};
 
	onload = initialize;
 
 
</script></html> 
 
